/* 此代码在windows环境下编译运行 */
#pragma warning(disable:4996)// 禁止code:4996报错
#include <iostream>
#include <string>
#include <cstring>
#include <WinSock2.h>// windows下socket的头文件

#pragma comment(lib, "ws2_32.lib")// 宏		导入Windows Socket 2.0 32bits的库

using namespace std;

enum
{
	WSASTARUP_ERR = 1,
	SOCKET_ERR
};

uint16_t serverPort = 3000;
string serverIP = "121.43.123.216";// 运行前，先配置serverIP

int main()
{
	WSAData wsd;
	// 启动WinSock
	if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)// MAKEWORD(2, 2) 构建一个2.2的库的版本，构建的结果放到wsd里
		// 将ws2_32.lib这个库导进来后，匹配2.2版本的套接字
	{
		cout << "WSAStartup Error " << WSAGetLastError() << endl;
		return WSASTARUP_ERR;
	}
	else
	{
		cout << "WSAStartup Success" << endl;
	}

	// Socket编程——start
	// 1. 创建套接字
	SOCKET/*unsigned int*/ csock = socket(AF_INET, SOCK_DGRAM, 0);
	if (csock == SOCKET_ERROR/*-1*/)
	{
		cout << "socket error = " << WSAGetLastError() << endl;
		return SOCKET_ERR;
	}
	else
	{
		cout << "socket success" << endl;
	}
	// 2. 
	struct sockaddr_in server;// 发消息给server
	memset(&server, 0, sizeof(server));
	server.sin_family = AF_INET;
	server.sin_port = htons(serverPort);// 用户不需要输入ip和端口号
	server.sin_addr.s_addr = inet_addr(serverIP.c_str());

	// 3. 通信
#define NUM 1024
	char buffer[NUM];
	string line;
	while (true)
	{
		cout << "Please Enter# ";

		getline(cin, line);
		// 发送
		int n = sendto(csock, line.c_str(), line.size(), 0, (struct sockaddr*)&server, sizeof(server));// 发给server
		if (n < 0)
		{
			cout << "sendto error" << endl;
			break;
		}
		// 接收
		struct sockaddr_in from;// 远端
		int fromLen = sizeof(from);
		buffer[0] = 0;// C 清空
		n = recvfrom(csock, buffer, sizeof(buffer) - 1, 0, (struct sockaddr*)&from, &fromLen);// 从csock中读，读到buffer中
		if (n > 0)
		{
			buffer[n] = 0;// 字符串
			cout << "服务器端返回消息# " << buffer << endl;
		}
		else
			break;
	}
	// Socket编程——end

	// 关闭套接字
	closesocket(csock);// 关不关都可，以为套接字本质是文件，文件是随进程的，当进程结束，文件随之关闭
	// 释放使用的ws2_32.lib相关
	WSACleanup();

	return 0;
}
